home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
MapMaker
/
Source
/
InputView.m
< prev
next >
Wrap
Text File
|
1990-12-08
|
11KB
|
512 lines
/* Generated by Interface Builder */
#import "InputView.h"
#import "ControlObject.h"
#import <appkit/appkit.h>
#import <math.h>
#import "constants.h"
#import "pointdata.h"
void doIMapping(PointList *p)
{
int t;
Point *pt;
int lastpen = UP;
float lastcol = NX_LTGRAY;
PSsetgray(NX_LTGRAY);
PSsetlinewidth(0.0);
for(t=gotoPointInList(p,0,&pt);(t);t=gotoNextPointInList(p,&pt)) {
if (lastpen == DOWN)
PSlineto(pt->x,pt->y);
else
PSmoveto(pt->x,pt->y);
if (lastcol != pt->pencolour) {
PSstroke();
PSnewpath();
PSmoveto(pt->x,pt->y);
PSsetgray(pt->pencolour);
}
lastpen = pt->pen;
lastcol = pt->pencolour;
}
PSstroke();
}
float AngleBetween(Point *pa, Point *pb, Point *p)
{
Point v1,v2;
float f;
v1.x = pa->x - p->x;
v1.y = pa->y - p->y;
v2.x = pb->x - p->x;
v2.y = pb->y - p->y;
f = ((v1.x * v2.x) + (v1.y * v2.y));
if (f == 0.0)
return (PI/2);
return fabs(acos(f/sqrt(fabs(f))));
}
@implementation InputView
- (BOOL)gridState
{
return GridOn;
}
- setGridState:(BOOL)newGridState
{
GridOn = newGridState;
return self;
}
- setItUp:sender
{
caller = sender;
inputMode = [sender inputMode];
inputX = [sender inputX];
inputY = [sender inputY];
inputPen = [sender inputPen];
[self setDrawSize:(IRight-ILeft) :(ITop-IBottom)];
[self setDrawOrigin:ILeft :IBottom];
[[self window] addToEventMask:
NX_LMOUSEDRAGGEDMASK|NX_MOUSEMOVEDMASK|NX_FLAGSCHANGEDMASK];
[[self window] makeFirstResponder:self];
instanceDrawing = NO;
state = WAITING;
newPointList(¤tPoints);
return self;
}
- drawGrid
{
float f;
for(f=ILeft;(f<=IRight);f=f+(PI/12)) {
PSmoveto(f,ITop);
PSlineto(f,IBottom);
}
for(f=0.0;(f<=ITop);f=f+(PI/12)) {
PSmoveto(ILeft,f);
PSlineto(IRight,f);
}
for(f=0.0;(f>=IBottom);f=f-(PI/12)) {
PSmoveto(ILeft,f);
PSlineto(IRight,f);
}
return self;
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
if (instanceDrawing) {
PSsetinstance(YES);
[self doInstanceDragSwitch];
} else {
PSsetinstance(NO);
NXEraseRect(&bounds);
PSsetgray(NX_LTGRAY);
PSsetlinewidth(0.0);
if (GridOn == YES)
[self drawGrid];
doIMapping(¤tPoints);
}
return self;
}
-saveFile
{
if (!savePanel) {
savePanel = [SavePanel new];
[savePanel setRequiredFileType:"map"];
}
if ([savePanel runModal])
if (savePointList(¤tPoints,(char *)[savePanel filename]))
return self;
else
NXRunAlertPanel("File System Error.","MapMaker couldn't save your map.",NULL,NULL,NULL);
else
return self;
}
- openFile:(const char *)filename
{
freePointList(¤tPoints);
newPointList(¤tPoints);
if (!(loadPointList(¤tPoints,(char *)filename)))
NXRunAlertPanel("File System Error.","MapMaker couln't load %s.",NULL,NULL,NULL,filename);
[caller getNewInput];
[caller refreshOutput];
[self display];
return self;
}
-openFile
{
if (!openPanel) {
openPanel = [OpenPanel new];
[openPanel setRequiredFileType:"map"];
}
if ([openPanel runModal]) {
[self openFile:[openPanel filename]];
}
return self;
}
-clearFile
{
freePointList(¤tPoints);
newPointList(¤tPoints);
[self display];
[caller getNewInput];
[caller refreshOutput];
return self;
}
- map:(PointList **)pl
{
*pl = ¤tPoints;
return self;
}
- mouseDown:(NXEvent *)theEvent
{
location = &(theEvent->location);
switch (state) {
case DELETING : instanceDrawing = YES;
[self display];
break;
case INSERTING : [self insertPoint:theEvent];
state = DMOVING;
MoveIndex = InsertIndex;
[self display];
break;
case MOVING : instanceDrawing = YES;
[self display];
break;
default : instanceDrawing = YES;
[self display];
break;
}
return self;
}
- mouseUp:(NXEvent *)theEvent
{
switch (state) {
case DELETING :
[self deletePoint:theEvent];
instanceDrawing = NO;
[self display];
break;
case INSERTING :
instanceDrawing = NO;
[self display];
break;
case MOVING : break;
case DMOVING :
[self movePoint:theEvent];
instanceDrawing = NO;
[self display];
[self fixState:theEvent];
break;
default : [self addPoint:theEvent];
instanceDrawing = NO;
[self display];
break;
}
return self;
}
- insertPoint:(NXEvent *)theEvent
{
NXPoint pt;
Point p,*p1,*p2,*p3;
int s,t,u;
float f,g;
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
p.x = pt.x;
p.y = pt.y;
p.pen = DOWN;
p.pencolour = NX_BLACK;
if (theEvent->flags&NX_ALTERNATEMASK)
p.pen = UP;
s = gotoPointInList(¤tPoints,InsertIndex-1,&p1);
if (s)
t = gotoNextPointInList(¤tPoints,&p2);
else
t = gotoPointInList(¤tPoints,InsertIndex,&p2);
if (t)
u = gotoNextPointInList(¤tPoints,&p3);
else
u = gotoPointInList(¤tPoints,InsertIndex+1,&p3);
if ((s) && (t) && (u)) {
f = AngleBetween(p1,&p,p2);
g = AngleBetween(p3,&p,p2);
if (f > g) {
InsertIndex++;
}
} else if ((s) && (t)) {
f = AngleBetween(p1,&p,p2);
if (f > (PI/2)) {
InsertIndex++;
}
} else if ((t) && (u)) {
f = AngleBetween(p3,&p,p2);
if (f <= (PI/2)) {
InsertIndex++;
}
} else {
InsertIndex = 0;
}
/* find slopes. */
s= insertInPointListAt(¤tPoints,&p,InsertIndex);
return self;
}
- movePoint:(NXEvent *)theEvent
{
NXPoint pt;
Point *p;
int s;
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
s = gotoPointInList(¤tPoints,MoveIndex,&p);
p->x = pt.x;
p->y = pt.y;
return self;
}
- addPoint:(NXEvent *)theEvent
{
NXPoint pt;
Point p;
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
p.x = pt.x;
p.y = pt.y;
p.pen = DOWN;
p.pencolour = NX_BLACK;
if (theEvent->flags&NX_ALTERNATEMASK)
p.pen = UP;
addToPointList(¤tPoints,&p);
return self;
}
- deletePoint:(NXEvent *)theEvent
{
int s,index;
NXPoint pt;
Point *p;
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
if ((!s) || ((POINTRADIUS * POINTRADIUS) < (((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
return self;
removeFromPointList(¤tPoints,index);
return self;
}
- doInstanceDragSwitch
{
NXPoint pt;
Point *p, *p1,*p2, *p3;
int s,t,u;
int index;
int hold1,hold2;
pt = *location;
[self convertPoint:&pt fromView:nil];
switch(state) {
case DELETING :
s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
if ((!s) || ((POINTRADIUS * POINTRADIUS) <
(((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
{
PSnewinstance();
break;
}
PSsetgray(NX_BLACK);
PSsetlinewidth(0.0);
PSnewinstance();
PSarc(p->x,p->y,POINTRADIUS,(2*PI),PI);
PSstroke();
break;
case INSERTING :
s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
if ((!s) || ((POINTRADIUS * POINTRADIUS) <
(((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y))))) {
PSnewinstance();
break;
}
InsertIndex = index;
PSsetgray(NX_BLACK);
PSsetlinewidth(0.0);
PSnewinstance();
PSarc(pt.x,pt.y, POINTRADIUS,(2*PI),PI);
PSstroke();
break;
case MOVING :
s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
if ((!s) || ((POINTRADIUS * POINTRADIUS) <
(((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
{
PSnewinstance();
break;
}
MoveIndex = index;
PSsetgray(NX_BLACK);
PSsetlinewidth(0.0);
PSnewinstance();
PSarc(p->x,p->y,POINTRADIUS,(2*PI),PI);
PSstroke();
break;
case DMOVING :
s =gotoPointInList(¤tPoints,MoveIndex-1,&p2);
if (s)
u = gotoNextPointInList(¤tPoints,&p1);
else
u = gotoPointInList(¤tPoints,MoveIndex,&p1);
if (u)
t = gotoNextPointInList(¤tPoints,&p3);
else
t = gotoPointInList(¤tPoints,MoveIndex+1,&p3);
PSsetgray(NX_BLACK);
PSsetlinewidth(0.0);
PSnewinstance();
if ((s) && (p2->pen == DOWN)) {
PSsetgray(NX_BLACK);
PSmoveto(p2->x,p2->y);
PSlineto(pt.x,pt.y);
} else {
PSmoveto(pt.x,pt.y);
}
if ((t) && (u) && (p1->pen == DOWN)) {
PSlineto(p3->x,p3->y);
}
PSstroke();
break;
default : s = lastPointInList(¤tPoints,&p);
if ((!s) || (p->pen == UP)) return self;
PSsetgray(NX_BLACK);
PSsetlinewidth(0.0);
PSnewinstance();
PSmoveto(p->x,p->y);
PSlineto(pt.x,pt.y);
PSstroke();
break;
}
return self;
}
- mouseDragged:(NXEvent *)theEvent
{
NXPoint pt;
char str[20];
pt = *location;
[self convertPoint:&pt fromView:nil];
sprintf(str,"%.1f",(pt.x)*(180/PI));
[inputX setStringValue:str];
sprintf(str,"%.1f",(pt.y)*(180/PI));
[inputY setStringValue:str];
switch (state) {
case DELETING :
location = &(theEvent->location);
[self display];
break;
case INSERTING : ;
case MOVING : state = DMOVING;
case DMOVING : location = &(theEvent->location);
[self display];
break;
default: location = &(theEvent->location);
[self display];
break;
}
return self;
}
- mouseMoved:(NXEvent *)theEvent
{
NXPoint pt;
char str[20];
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
sprintf(str,"%.1f",(pt.x)*(180/PI));
[inputX setStringValue:str];
sprintf(str,"%.1f",(pt.y)*(180/PI));
[inputY setStringValue:str];
switch (state) {
case MOVING :
instanceDrawing = YES;
location = &(theEvent->location);
[self display];
break;
case DELETING :
instanceDrawing = YES;
location = &(theEvent->location);
[self display];
break;
case INSERTING :
instanceDrawing = YES;
location = &(theEvent->location);
[self display];
break;
default: if(instanceDrawing) {
instanceDrawing = NO;
[self display];
}
break;
}
}
- fixState:(NXEvent *)theEvent
{
state = WAITING;
if (theEvent->flags&NX_ALPHASHIFTMASK)
state = DELETING;
if (theEvent->flags&NX_CONTROLMASK)
state = INSERTING;
if (theEvent->flags&NX_COMMANDMASK)
state = MOVING;
switch (state) {
case DELETING : [inputMode setStringValue:"Deleting"]; break;
case INSERTING : [inputMode setStringValue:"Inserting"]; break;
case MOVING : [inputMode setStringValue:"Moving"]; break;
case WAITING : [inputMode setStringValue:"Waiting"]; break;
default : [inputMode setStringValue:"Barfing"]; break;
}
return self;
}
- flagsChanged:(NXEvent *)theEvent
{
if (theEvent->flags&NX_ALTERNATEMASK)
[inputPen setStringValue:"Up"];
else
[inputPen setStringValue:"Down"];
[self fixState:theEvent];
return self;
}
@end